﻿using Brc_DSB.GetWay.Configuration;
using Brc_DSB.GetWay.DataBase;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Ocelot.Configuration;
using Ocelot.DependencyInjection;
using Ocelot.Logging;
using Ocelot.Middleware;
using Ocelot.Middleware.Pipeline;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace Brc_DSB.GetWay.Middleware
{
    /// <summary>
    /// 扩展方法，加入到Ocelot管道中
    /// </summary>
    public static class AuthMiddlewareExtension
    {
        public static IOcelotPipelineBuilder UseAuthMiddleware(this IOcelotPipelineBuilder builder)
        {
            return builder.UseMiddleware<AuthMiddleware>();
        }
    }
    /// <summary>
    /// 中间件在管道中工作
    /// </summary>
    public class AuthMiddleware : OcelotMiddleware
    {
        private readonly OcelotRequestDelegate _next;
        private readonly DbConfiguration _options;
        private readonly IAuthRepository _auth;
        public AuthMiddleware(OcelotRequestDelegate next,
            IOcelotLoggerFactory loggerFactory,
            IAuthRepository auth,
            DbConfiguration options)
            : base(loggerFactory.CreateLogger<AuthMiddleware>())
        {
            _next = next;
            _auth = auth;
            _options = options;
        }

        public async Task Invoke(DownstreamContext context)
        {
            if (!context.IsError && context.HttpContext.Request.Method.ToUpper() != "OPTIONS")
            {
                if (!_options.ClientAuthorization)
                {
                    Logger.LogInformation($"未启用客户端授权管道");
                    await _next.Invoke(context);
                }
                else
                {
                    Logger.LogInformation($"{context.HttpContext.Request.Path} 是认证路由. {MiddlewareName} 开始校验授权信息");
                    #region 提取客户端ID
                    var path = context.DownstreamReRoute.UpstreamPathTemplate.OriginalValue; //路由地址
                    var isAuth = context.HttpContext.Request.Headers.ContainsKey("Brc_Auth");
                    if (!isAuth)
                    {
                        var errResult = new { errcode = 401, errmsg = "未包含授权验证参数" };
                        var message = Newtonsoft.Json.JsonConvert.SerializeObject(errResult);
                        context.HttpContext.Response.StatusCode = (int)HttpStatusCode.OK;
                        await context.HttpContext.Response.WriteAsync(message);
                        return;
                    }
                    var clientId = context.HttpContext.Request.Headers["Brc_Auth"].ToString();
                    #endregion
                    if (await _auth.CheckClientAuthenticationAsync(clientId, path))
                    {
                        await _next.Invoke(context);
                    }
                    else
                    {//未授权直接返回错误
                        var errResult = new { errcode = 401, errmsg = "请求地址未授权" };
                        var message = Newtonsoft.Json.JsonConvert.SerializeObject(errResult);
                        context.HttpContext.Response.StatusCode = (int)HttpStatusCode.OK;
                        await context.HttpContext.Response.WriteAsync(message);
                        return;
                    }
                }
            }
            else
            {
                await _next.Invoke(context);
            }
        }
       
    }
}
